package com.qinhailin.portal.dbm.service;

import java.util.List;

import com.jfinal.aop.Inject;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Model;
import com.qinhailin.common.base.service.BaseService;
import com.qinhailin.common.model.BaseModel;


public abstract class BaseServiceImpl<T extends BaseModel<T>> extends BaseService {
	
	protected CPGetIDService idService;		// 调用存储过程
	
	protected T dao = null;
	/** 默认SQL语句 类似于: SELECT * FROM table **/
	protected String sql;
	/** FIND1 **/
	protected String top1Sql;
	
	protected String table;
	protected String primaryKey;
	
	/**
	public BaseServiceImpl(T dao) {
		this.dao = dao;
		this.sql = "SELECT * FROM " + dao.tableName();
	}
	**/
	@Override
	public Model<?> getDao() {
		return dao;
	}
	
	
	
	/** 
	 * <p>数据库类型,写在配置文件AppConfig.txt中. 目前只支持SQLSERVER和MYSQL</p>
	 * <p>dbtype=</p>
	 * <p>
	 * 		sqlserver,mysql
	 * </p>
	 **/
	protected String dbtype;
	
	
	
	/**审核:2019-10-18**/
	public Integer save(List<T> objs) {
		return this.save(objs, 100);
	}
	
	/**审核:2019-10-18**/
	public Integer save(List<T> objs, Integer qty) {
		int[] rs = Db.batchSave(objs, qty);
		Integer r = 0;
		for(int i : rs) {
			r += i;
		}
		return r;
	}

	
	/**
	 * <p>在构造函数里生成默认SELECT语句</p>
	 * <p>不建议重写</p>
	 * <p>审核:2019-10-18</p>
	 * @param table 表名
	 * @return 完整的默认SELECT语句. SELECT * FROM table
	 */
	protected String genSELECT() {
		return "SELECT * FROM " + this.table;
	}
	
	/**
	 * <p>在构造函数里生成默认SELECT语句</p>
	 * <p>不建议重写</p>
	 * <p>审核:2019-10-18</p>
	 * @param table 表名
	 * @return 完整的默认SELECT语句. SELECT * FROM table
	 */
	protected String genTop1SELECT() {
		return "SELECT " + (this.table.equals("sqlserver") ? "TOP(1)" : "") + " * FROM " + this.table + (this.table.equals("sqlserver") ? "" : " LIMIT 1");
	}
	
	
	/**
	 * <p>构造函数</p>
	 * <p>审核:2019-10-18</p>
	 * <p>2019-11-18 禁用数据类型功能.目前都是使用SQLSERVER</p>
	 * @param dao DAO
	 * @param table 表名
	 * @param primaryKey 主键
	 */
	public BaseServiceImpl(T dao, String table, String primaryKey) {
		// 2019-11-18 01:05:43 禁用这个功能
		//this.dbtype = PropKit.use("AppConfig.txt").get("dbtype", "sqlserver");
		this.dbtype = "sqlserver";
		idService = new CPGetIDService();
		this.dao = dao;
		this.table = table;
		this.primaryKey = primaryKey;
		this.sql = this.genSELECT();
		this.top1Sql = this.genTop1SELECT();
		
		
	}
	
	
	/**
	 * <p>新-构造函数,推荐使用这个</p>
	 * <p>审核:2019-10-18</p>
	 * @param dao DAO
	 */
	public BaseServiceImpl(T dao) {
		this(dao, dao.tableName(), dao.primaryKey());
	}
//	
//	/** <p>审核:2019-10-18</p> **/
//	@Override
//	public Boolean save(T object) {
//		return object.save();
//	}
//
//	/** <p>审核:2019-10-18</p> **/
//	@Override
//	public Boolean update(T object) {
//		return object.update();
//	}
//
//	/** <p>审核:2019-10-18</p> **/
//	@Override
//	public Boolean delete(T object) {
//		return object.delete();
//	}

	/* (non-Javadoc)
	 * @see com.uuerp.service.IService#findBySID(java.lang.Integer)
	 */
//	@Override
//	public T findByID(Integer id) {
//		return id == null ? null : this.dao.findById(id);
//	}

	/** <p>审核:2019-10-18</p> **/
	public T findBySql(String sql, Object... params) {
		return this.dao.findFirst(sql, params);
	}

	/** <p>审核:2019-10-18</p> **/
	public java.util.List<T> list() {
		return this.dao.find(this.sql);
	}

	/** <p>审核:2019-10-18</p> **/
	public java.util.List<T> list(Integer page, Integer pageSize) {
		return this.list(this.sql, page, pageSize, null);
	}
	
	/** <p>审核:2019-10-18</p> <p>2019-11-18 </p>**/
	public java.util.List<T> list(String sql, Integer page, Integer pageSize, String orderBy, Object... params) {
		
		
		if(page == null || pageSize == null || page <= 0 || pageSize <= 0) {
			return this.List(sql, params);
		}
		
		String str = "";
		if(this.dbtype.contentEquals("sqlserver")) {
			str = 		" SELECT * FROM ( " + 
							" SELECT ROW_NUMBER() OVER(ORDER BY " + (orderBy != null && orderBy.length() > 0 ? orderBy : this.primaryKey) + " ) as _ID, m.* FROM ( " + sql + " ) AS m " + 
						" ) AS t" +
						" WHERE t._ID BETWEEN " + (page * pageSize - pageSize + 1) + " AND " + (page * pageSize)
						;
		}else {
			str = 	sql + (orderBy != null && orderBy.length() > 0 ? " ORDER BY " + orderBy : "") + " LIMIT " + (page * pageSize - pageSize + 1) + "," + pageSize;
		}
		
		return this.List(str, params);
	}

	
	

	/** <p>审核:2019-10-18</p> **/
	public java.util.List<T> List(String sql, Object... params) {
		return this.dao.find(sql, params);
	}

	/** <p>审核:2019-10-18</p> **/
	public Integer count() {
		// WAIT! 万一行数超过INT呢?
		Integer rs = 0;
		try {
			rs = this.dao.findFirst("SELECT COUNT(*) AS xQty FROM " + this.table).getInt("xQty");
		}catch(Exception e) {
			rs = 0;
		}
		return rs;
	}

	/** <p>审核:2019-10-18</p> **/
	public Integer count(String sql, Object... params) {
		//List<T> temp = this.dao.find(" SELECT COUNT(*) AS xQty FROM (" + sql + " ) AS m", params);
		
		Integer rs = 0;
		try {
			rs = this.dao.findFirst(" SELECT COUNT(*) AS xQty FROM (" + sql + " ) AS m ", params).getInt("xQty");
		}catch(Exception e) {
			rs = 0;
		}
		return rs;
	}

	/** <p>审核:2019-10-18</p> **/
	public Boolean delete(Object... ids) {
		T t = this.dao.findByIds(ids);
		return t != null ? this.delete(t) : null;
	}

//	@Override
//	public T find(Object... params) {
//		return this.dao.findByIds(params);
//	}

	/**
	 * <p>生成sID</p>
	 * <p>2019-11-20</p>
	 * @param obj
	 * @return
	 */
	//protected abstract T initPrimaryKey(T obj);
	
	/**
	 * <p>生成sID</p>
	 * <p>2019-11-20 对于在表内递增的支持并不好,因此不可使用主键类型=1表内自增的,只允许使用2!</p>
	 * @param obj
	 * @return
	 */
	//protected abstract List<T> initPrimaryKey(List<T> objs);
	
	
	
}
